package com.bbva.itradecomex.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.bbva.itradecomex.bo.iface.ConsultaComunBO;
import com.bbva.itradecomex.domain.Banco;
import com.bbva.itradecomex.domain.Moneda;
import com.bbva.itradecomex.domain.MultiTabla;
import com.bbva.itradecomex.domain.Pais;
import com.bbva.itradecomex.domain.ProductoBaseMT;
import com.bbva.itradecomex.domain.TipoDocumento;
import com.bbva.itradecomex.util.Constantes;
import com.bbva.itradecomex.util.ITradexUtil;

@Controller
@RequestScoped
@ManagedBean
public class ComunController {
	
	private static final Logger log = Logger.getLogger(ComunController.class);
	
	@Autowired
	private ConsultaComunBO consultaComunBO;
	
	private Pais paisSeleccionado;
	private Banco bancoSeleccionado;
	private Moneda monedaSeleccionado;
	private TipoDocumento tipoDocSeleccionado;
	private List<SelectItem> listTipoDocumento;
	private MultiTabla exclusivBancoSeleccionado;
	private List<SelectItem> listExclusividadBanco;
	private MultiTabla exclusivAladiSeleccionado;
	private List<SelectItem> listExclusividadAladi;
	private MultiTabla tipoOperacionSeleccionado;
	private List<SelectItem> listTipoOperacion;
	private MultiTabla situacionSeleccionado;
	private List<SelectItem> listSituacion;
	private MultiTabla exclusivBancoClaveSeleccionado;
	private List<SelectItem> listExclusividadBancoClave;
	
	private MultiTabla mesSeleccionado;
	private List<SelectItem> listMes;
	private MultiTabla tipoComparacionSeleccionado;
	private List<SelectItem> listTipoComparacion;
	
	private List<ProductoBaseMT> listProductoMTSeleccionado;
	private List<SelectItem> listProductoMT;
	private List<ProductoBaseMT> listSubProductoMTSeleccionado;
	private List<SelectItem> listSubProductoMT;
	private MultiTabla exclusivOperSeleccionado;
	private List<SelectItem> listExclusivOper;
	
	public void logoutListener(){
		FacesContext ctx = FacesContext.getCurrentInstance();
        ExternalContext extContext = ctx.getExternalContext();
        String url = extContext.encodeActionURL(ctx.getApplication().getViewHandler().getActionURL(ctx, "/login.xhtml"));
        try {
            extContext.redirect(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
	}

	public List<Pais> completarPais(String inPais) {
		String pais = "";
		if(inPais != null){
			pais = inPais;
		}
		
		try {
			return consultaComunBO.getListBusquedaPais(pais.trim());
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage(),e);
		}
		return null;
	}
	
	public List<Moneda> completarMoneda(String inMoneda) {
		try {
			return consultaComunBO.getListBusquedaMoneda(inMoneda.trim());
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage(),e);
		}
		return null;
	}
	
	public List<Banco> completarBanco(String inNombreBanco) {
		String codPais = "";
		
		if(paisSeleccionado != null){
			codPais = paisSeleccionado.getCodPais();
		}
		
		try {
			return consultaComunBO.getListBusquedaBanco(codPais, inNombreBanco.trim());
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage(),e);
		}
		return null;
	}
	
	public void cargarListTipoDocumento() throws Exception{
		this.listTipoDocumento = new ArrayList<SelectItem>();
		List<TipoDocumento> list = consultaComunBO.getListBusquedaTipoDocumento();
		if(list != null){			
			for (TipoDocumento tipoDocumento : list) {
				this.listTipoDocumento.add(new SelectItem(tipoDocumento, tipoDocumento.getDescripcion()));
			}
		}
	}
	
	public void cargarListTipoDocumento2() throws Exception{
		this.listTipoDocumento = new ArrayList<SelectItem>();
		List<TipoDocumento> list = consultaComunBO.getListBusquedaTipoDocumento2();
		if(list != null){			
			for (TipoDocumento tipoDocumento : list) {
				this.listTipoDocumento.add(new SelectItem(tipoDocumento, tipoDocumento.getDescripcion()));
			}
		}
	}
	
	public void cargarExclusividadBancos() throws Exception{
		this.listExclusividadBanco = getListSelectItem(Constantes.IDTABLA_EXCLUSIVIDAD_BANCOS);
	}
	
	public void cargarExclusividadAladi() throws Exception{
		this.listExclusividadAladi = getListSelectItem(Constantes.IDTABLA_EXCLUSIVIDAD_ALADI);
	}
	
	public void cargarTipoOperacion() throws Exception{
		this.listTipoOperacion = getListSelectItem(Constantes.IDTABLA_TIPO_OPERACION);
	}
	
	public void cargarSituacion() throws Exception{
		this.listSituacion = getListSelectItem(Constantes.IDTABLA_SITUACION);
	}
	public void cargarExclusividadBancosClave() throws Exception{
		this.listExclusividadBancoClave = getListSelectItem(Constantes.IDTABLA_EXCLUSIVIDAD_BANCOS_CON_CLAVE);
	}
	public void cargarTipoComparacion() throws Exception{
		this.listTipoComparacion = getListSelectItem(Constantes.IDTABLA_PCOMEX_TIPO_COMPARACION);
	}
	public void cargarMeses(String strCodVal) throws Exception{
		this.listMes = getListSelectItemValorTipoC(strCodVal);//Constantes.IDTABLA_PCOMEX_VALOR_COMP_MENSUAL
	}
	
	private List<SelectItem> getListSelectItem(String data) throws Exception{
		List<SelectItem> listSelectItem = new ArrayList<SelectItem>();
		List<MultiTabla> list = consultaComunBO.getListBusquedaMultiTabla(data);

		if(list != null && list.size() > 0){
			for (MultiTabla multiTabla : list) {
				listSelectItem.add(new SelectItem(multiTabla, multiTabla.getDescripcion()));
			}
		}

		return listSelectItem;
	}

	private List<SelectItem> getListSelectItemValorTipoC(String data) throws Exception{
		List<SelectItem> listSelectItem = new ArrayList<SelectItem>();
		List<MultiTabla> list = consultaComunBO.getListBusquedaValorTipoC(data);

		if(list != null && list.size() > 0){
			for (MultiTabla multiTabla : list) {
				listSelectItem.add(new SelectItem(multiTabla, multiTabla.getDescripcion()));
			}
		}

		return listSelectItem;
	}
	
	public void cargarListProductoMT() throws Exception{
		listProductoMT = new ArrayList<SelectItem>();
		List<ProductoBaseMT> list = consultaComunBO.getListProductoMT();
		if(list != null && list.size() > 0){
			listProductoMTSeleccionado = list;
			listProductoMT = getListSelectItemProdBaseMT(list);
		}
		cargarDependenciaProductoMT();
	}
	
	public void cargarDependenciaProductoMT() throws Exception{
		String array = getArrayCodigo(listProductoMTSeleccionado, Constantes.COMA, true);
		cargarListSubProductoMT(array);
		cargarListExclusividadOper(array);
	}
	
	private void cargarListSubProductoMT(String array) throws Exception{
		if(array != null && array.length() > 0){
			List<ProductoBaseMT> listProdMT = consultaComunBO.getListSubProductoMT(array);

			if(listProdMT != null && listProdMT.size() > 0){
				if(listSubProductoMT == null){
					listSubProductoMT = getListSelectItemProdBaseMT(listProdMT);
					listSubProductoMTSeleccionado = listProdMT;
				}else{
					boolean isEquals = compararListaChekSegNivel(listProdMT, listSubProductoMT);
					
					if(!isEquals){
						List<SelectItem> listSelectItemTemp = new ArrayList<SelectItem>(listSubProductoMT);
						List<ProductoBaseMT> listProdTemp = selectItemToProductoMT(listSelectItemTemp);

						listSubProductoMT = getListSelectItemProdBaseMT(listProdMT);
						
						List<ProductoBaseMT> listProdSeleccionadoTemp = new ArrayList<ProductoBaseMT>(listSubProductoMTSeleccionado);
						listSubProductoMTSeleccionado = listProdMT;
						if(listProdSeleccionadoTemp != null && listProdSeleccionadoTemp.size() > 0){
							int i = 0;
							while(i < listProdMT.size()){
								ProductoBaseMT productoBaseMT =  listProdMT.get(i);
								boolean isContent = false;
								for(int j = 0; j < listProdSeleccionadoTemp.size(); j ++){
									ProductoBaseMT p = listProdSeleccionadoTemp.get(j);
									if(productoBaseMT.getCodProductoBaseMT().equals(p.getCodProductoBaseMT())){
										isContent = true;
										break;
									}
								}
								if(!isContent){
									for(int j = 0; j < listProdTemp.size(); j++){
										ProductoBaseMT p = listProdTemp.get(j);
										if(productoBaseMT.getCodProductoBaseMT().equals(p.getCodProductoBaseMT())){
											isContent = true;
											break;
										}
									}
									if(isContent){
										listSubProductoMTSeleccionado.remove(i);
										i--;
									}
								}
								i++;
							}
						}else{
							int i = 0;
							while(i < listProdMT.size()){
								ProductoBaseMT productoBaseMT =  listProdMT.get(i);
								boolean isContent = false;
								for(int j = 0; j < listProdTemp.size(); j++){
									ProductoBaseMT p = listProdTemp.get(j);
									if(productoBaseMT.getCodProductoBaseMT().equals(p.getCodProductoBaseMT())){
										isContent = true;
										break;
									}
								}
								if(isContent){
									listSubProductoMTSeleccionado.remove(i);
									i--;
								}
								i++;
							}
						}
					}
				}
			}else{
				listSubProductoMT = null;
				listSubProductoMTSeleccionado = null;
			}
		}else{
			listSubProductoMT = null;
			listSubProductoMTSeleccionado = null;
		}
	}
	
	private List<ProductoBaseMT> selectItemToProductoMT(List<SelectItem> listSelectItem){
		List<ProductoBaseMT> listProd = null;
		if(listSelectItem != null && listSelectItem.size() > 0){
			listProd = new ArrayList<ProductoBaseMT>();
			for(int i = 0; i<listSelectItem.size(); i++){
				SelectItem item = listSelectItem.get(i);
				ProductoBaseMT prod = (ProductoBaseMT)item.getValue();
				listProd.add(prod);
			}
		}
		return listProd;
	}
	
	private void cargarListExclusividadOper(String array) throws Exception{
		if(array != null && array.length() > 0){
			List<MultiTabla> list = consultaComunBO.getListExclusividadOper(array);

			if(list != null && list.size() > 0){
				if(listExclusivOper == null){
					listExclusivOper = getListSelectItemExclusivOper(list);
				}else{
					boolean isEquals = compararListaOperExclusv(list, listExclusivOper);
					
					if(!isEquals){
						listExclusivOper = getListSelectItemExclusivOper(list);
					}
				}
			}else{
				listExclusivOper = null;
				exclusivOperSeleccionado = null;
			}
		}else{
			listExclusivOper = null;
			exclusivOperSeleccionado = null;
		}
	}
	
	private List<SelectItem> getListSelectItemExclusivOper(List<MultiTabla> list){
		List<SelectItem> listSelectItem = new ArrayList<SelectItem>();
		
		for (MultiTabla multiTabla : list) {
			listSelectItem.add(new SelectItem(multiTabla, multiTabla.getDescripcion()));
		}
		
		return listSelectItem;
	}
	
	private List<SelectItem> getListSelectItemProdBaseMT(List<ProductoBaseMT> list){
		List<SelectItem> listSelectItem = new ArrayList<SelectItem>();

		for (ProductoBaseMT productoBaseMT : list) {
			listSelectItem.add(new SelectItem(productoBaseMT, productoBaseMT.getDescripcion()));
		}
		
		return listSelectItem;
	}
	
	private boolean compararListaOperExclusv(List<MultiTabla> list, List<SelectItem> listSelectItem){
		boolean isEquals = true;

		int tam1 = list.size();
		int tam2 = listSelectItem.size();

		if(tam1 == tam2){
			for(int i = 0; i<tam1; i++){
				SelectItem item2 = listSelectItem.get(i);
				MultiTabla m1 = list.get(i);
				MultiTabla m2 = (MultiTabla)item2.getValue();
				String valor1 = m1.getValor1() == null ? Constantes.VACIO : m1.getValor1();
				String valor2 = m2.getValor1() == null ? Constantes.VACIO : m2.getValor1();
				if(!valor1.equals(valor2)){
					isEquals = false;
					break;
				}
			}
		}else{
			isEquals = false;
		}

		return isEquals;
	}
	
	private boolean compararListaChekSegNivel(List<ProductoBaseMT> list, List<SelectItem> listSelectItem){
		boolean isEquals = true;

		int tam1 = list.size();
		int tam2 = listSelectItem.size();

		if(tam1 == tam2){
			for(int i = 0; i<tam1; i++){
				SelectItem item2 = listSelectItem.get(i);
				ProductoBaseMT m1 = list.get(i);
				ProductoBaseMT m2 = (ProductoBaseMT)item2.getValue();
				String valor1 = m1.getCodProductoBaseMT() == null ? Constantes.VACIO : m1.getCodProductoBaseMT();
				String valor2 = m2.getCodProductoBaseMT() == null ? Constantes.VACIO : m2.getCodProductoBaseMT();
				if(!valor1.equals(valor2)){
					isEquals = false;
					break;
				}
			}
		}else{
			isEquals = false;
		}

		return isEquals;
	}
	
	public String getArrayCodigo(List<ProductoBaseMT> list, String separador, boolean isCodigo){
		String arrayCodigo = Constantes.VACIO;
		if(list != null && list.size() > 0){
			StringBuilder sb = new StringBuilder(Constantes.VACIO);
			for (ProductoBaseMT productoBaseMT : list) {
				String dato;
				if(isCodigo){
					dato = productoBaseMT.getCodProductoBaseMT();
				}else{
					dato = productoBaseMT.getDescripcion() + "  ";
				}
				if(dato != null && dato.trim().length() > 0){
					sb.append(separador);
					sb.append(dato);
				}
			}
			
			arrayCodigo = sb.toString();
			
			if(arrayCodigo.length() > 1){
				return arrayCodigo.substring(1, arrayCodigo.length());
			}else{
				return Constantes.VACIO;
			}
		}
		return arrayCodigo;
	}
	
	public boolean validarColorFecha(String fecha, String tipo){
		Date dFecha = ITradexUtil.stringToDate(fecha, Constantes.FORMAT_DATE_yyyyMMdd);
		
		if(Constantes.VALOR_CERO.equals(tipo)){
			return ITradexUtil.esFecha1MayorFecha2(dFecha, new Date());
		}else {
			return !ITradexUtil.esFecha1MayorFecha2(dFecha, new Date());
		}
	}
	
	public void inicializarValores(){
		this.paisSeleccionado = null;
		this.bancoSeleccionado = null;
		this.monedaSeleccionado = null;
		this.listTipoDocumento = null;
		this.tipoDocSeleccionado = null;
		this.exclusivBancoSeleccionado = null;
		this.listExclusividadBanco = null;
		this.exclusivAladiSeleccionado = null;
		this.listExclusividadAladi = null;
		this.tipoOperacionSeleccionado = null;
		this.listTipoOperacion = null;
		this.situacionSeleccionado = null;
		this.listSituacion = null;
		this.exclusivBancoClaveSeleccionado=null;
		this.listExclusividadBancoClave=null;
		this.mesSeleccionado = null;
		this.listMes=null;
		this.tipoComparacionSeleccionado=null;
		this.listTipoComparacion=null;
		this.listProductoMTSeleccionado = null;
		this.listProductoMT = null;
		this.listSubProductoMTSeleccionado = null;
		this.listSubProductoMT = null;
		this.exclusivOperSeleccionado = null;
		this.listExclusivOper = null;
	}
	
	public Banco getBancoSeleccionado() {
		return bancoSeleccionado;
	}
	public void setBancoSeleccionado(Banco bancoSeleccionado) {
		this.bancoSeleccionado = bancoSeleccionado;
	}
	public Pais getPaisSeleccionado() {
		return paisSeleccionado;
	}
	public void setPaisSeleccionado(Pais paisSeleccionado) {
		this.paisSeleccionado = paisSeleccionado;
	}

	public Moneda getMonedaSeleccionado() {
		return monedaSeleccionado;
	}

	public void setMonedaSeleccionado(Moneda monedaSeleccionado) {
		this.monedaSeleccionado = monedaSeleccionado;
	}

	public List<SelectItem> getListTipoDocumento() {
		return listTipoDocumento;
	}

	public void setListTipoDocumento(List<SelectItem> listTipoDocumento) {
		this.listTipoDocumento = listTipoDocumento;
	}

	public TipoDocumento getTipoDocSeleccionado() {
		return tipoDocSeleccionado;
	}

	public void setTipoDocSeleccionado(TipoDocumento tipoDocSeleccionado) {
		this.tipoDocSeleccionado = tipoDocSeleccionado;
	}

	public MultiTabla getExclusivBancoSeleccionado() {
		return exclusivBancoSeleccionado;
	}

	public void setExclusivBancoSeleccionado(MultiTabla exclusivBancoSeleccionado) {
		this.exclusivBancoSeleccionado = exclusivBancoSeleccionado;
	}
	public List<SelectItem> getListExclusividadBanco() {
		return listExclusividadBanco;
	}

	public void setListExclusividadBanco(List<SelectItem> listExclusividadBanco) {
		this.listExclusividadBanco = listExclusividadBanco;
	}

	public MultiTabla getExclusivAladiSeleccionado() {
		return exclusivAladiSeleccionado;
	}

	public void setExclusivAladiSeleccionado(MultiTabla exclusivAladiSeleccionado) {
		this.exclusivAladiSeleccionado = exclusivAladiSeleccionado;
	}

	public List<SelectItem> getListExclusividadAladi() {
		return listExclusividadAladi;
	}

	public void setListExclusividadAladi(List<SelectItem> listExclusividadAladi) {
		this.listExclusividadAladi = listExclusividadAladi;
	}

	public MultiTabla getTipoOperacionSeleccionado() {
		return tipoOperacionSeleccionado;
	}

	public void setTipoOperacionSeleccionado(MultiTabla tipoOperacionSeleccionado) {
		this.tipoOperacionSeleccionado = tipoOperacionSeleccionado;
	}

	public List<SelectItem> getListTipoOperacion() {
		return listTipoOperacion;
	}

	public void setListTipoOperacion(List<SelectItem> listTipoOperacion) {
		this.listTipoOperacion = listTipoOperacion;
	}

	public MultiTabla getSituacionSeleccionado() {
		return situacionSeleccionado;
	}

	public void setSituacionSeleccionado(MultiTabla situacionSeleccionado) {
		this.situacionSeleccionado = situacionSeleccionado;
	}

	public List<SelectItem> getListSituacion() {
		return listSituacion;
	}

	public void setListSituacion(List<SelectItem> listSituacion) {
		this.listSituacion = listSituacion;
	}

	public MultiTabla getExclusivBancoClaveSeleccionado() {
		return exclusivBancoClaveSeleccionado;
	}

	public void setExclusivBancoClaveSeleccionado(
			MultiTabla exclusivBancoClaveSeleccionado) {
		this.exclusivBancoClaveSeleccionado = exclusivBancoClaveSeleccionado;
	}

	public List<SelectItem> getListExclusividadBancoClave() {
		return listExclusividadBancoClave;
	}

	public void setListExclusividadBancoClave(
			List<SelectItem> listExclusividadBancoClave) {
		this.listExclusividadBancoClave = listExclusividadBancoClave;
	}

	public MultiTabla getMesSeleccionado() {
		return mesSeleccionado;
	}

	public void setMesSeleccionado(MultiTabla mesSeleccionado) {
		this.mesSeleccionado = mesSeleccionado;
	}

	public List<SelectItem> getListMes() {
		return listMes;
	}

	public void setListMes(List<SelectItem> listMes) {
		this.listMes = listMes;
	}

	public MultiTabla getTipoComparacionSeleccionado() {
		return tipoComparacionSeleccionado;
	}

	public void setTipoComparacionSeleccionado(
			MultiTabla tipoComparacionSeleccionado) {
		this.tipoComparacionSeleccionado = tipoComparacionSeleccionado;
	}

	public List<SelectItem> getListTipoComparacion() {
		return listTipoComparacion;
	}

	public void setListTipoComparacion(List<SelectItem> listTipoComparacion) {
		this.listTipoComparacion = listTipoComparacion;
	}

	public List<ProductoBaseMT> getListProductoMTSeleccionado() {
		return listProductoMTSeleccionado;
	}

	public void setListProductoMTSeleccionado(
			List<ProductoBaseMT> listProductoMTSeleccionado) {
		this.listProductoMTSeleccionado = listProductoMTSeleccionado;
	}

	public List<SelectItem> getListProductoMT() {
		return listProductoMT;
	}

	public void setListProductoMT(List<SelectItem> listProductoMT) {
		this.listProductoMT = listProductoMT;
	}

	public List<ProductoBaseMT> getListSubProductoMTSeleccionado() {
		return listSubProductoMTSeleccionado;
	}

	public void setListSubProductoMTSeleccionado(
			List<ProductoBaseMT> listSubProductoMTSeleccionado) {
		this.listSubProductoMTSeleccionado = listSubProductoMTSeleccionado;
	}

	public List<SelectItem> getListSubProductoMT() {
		return listSubProductoMT;
	}

	public void setListSubProductoMT(List<SelectItem> listSubProductoMT) {
		this.listSubProductoMT = listSubProductoMT;
	}

	public MultiTabla getExclusivOperSeleccionado() {
		return exclusivOperSeleccionado;
	}

	public void setExclusivOperSeleccionado(MultiTabla exclusivOperSeleccionado) {
		this.exclusivOperSeleccionado = exclusivOperSeleccionado;
	}

	public List<SelectItem> getListExclusivOper() {
		return listExclusivOper;
	}

	public void setListExclusivOper(List<SelectItem> listExclusivOper) {
		this.listExclusivOper = listExclusivOper;
	}
}
